using System.Globalization;
using System.Windows;
using System.Windows.Media;

namespace RRX.Xml.Helper
{
    public class BrushSerializer
    {
        // Serialize an object to string using XML serialization

        public static string Serialize(Brush brush)
        {
            if (brush is SolidColorBrush solidColorBrush)
            {
                return SerializeSolidColorBrush(solidColorBrush);
            }
            else if (brush is LinearGradientBrush linearGradientBrush)
            {
                return SerializeLinearGradientBrush(linearGradientBrush);
            }
            else if (brush is RadialGradientBrush radialGradientBrush)
            {
                return SerializeRadialGradientBrush(radialGradientBrush);
            }
            else
            {
                throw new ArgumentException("Unsupported brush type");
            }
        }

        private static string SerializeSolidColorBrush(SolidColorBrush solidColorBrush)
        {
            return $"sc:{solidColorBrush.Color}";
        }
        private static string SerializeLinearGradientBrush(LinearGradientBrush linearGradientBrush)
        {
            string startPoint = linearGradientBrush.StartPoint.X.ToString(CultureInfo.InvariantCulture) + ";" + linearGradientBrush.StartPoint.Y.ToString(CultureInfo.InvariantCulture);
            string endPoint = linearGradientBrush.EndPoint.X.ToString(CultureInfo.InvariantCulture) + ";" + linearGradientBrush.EndPoint.Y.ToString(CultureInfo.InvariantCulture);
            // string gradientStops = string.Join("|", linearGradientBrush.GradientStops.Select(stop => stop.Color + ";" + stop.Offset.ToString(CultureInfo.InvariantCulture)));
            string gradientStops = FormatGradientStops(linearGradientBrush.GradientStops);
            return $"lg:{startPoint}:{endPoint}:{gradientStops}";
        }

        private static string SerializeRadialGradientBrush(RadialGradientBrush radialGradientBrush)
        {
            string center = radialGradientBrush.Center.X.ToString(CultureInfo.InvariantCulture) + ";" + radialGradientBrush.Center.Y.ToString(CultureInfo.InvariantCulture);
            //string gradientStops = string.Join("|", radialGradientBrush.GradientStops.Select(stop => stop.Color + ";" + stop.Offset.ToString(CultureInfo.InvariantCulture)));
            string gradientStops = FormatGradientStops(radialGradientBrush.GradientStops);
            return $"rg:{center}:{gradientStops}";
        }

        public static Brush Deserialize(string serializedBrush)
        {
            if (serializedBrush.StartsWith("sc:"))
            {
                return DeserializeSolidColorBrush(serializedBrush);
            }
            else if (serializedBrush.StartsWith("lg:"))
            {
                return DeserializeLinearGradientBrush(serializedBrush);
            }
            else if (serializedBrush.StartsWith("rg:"))
            {
                return DeserializeRadialGradientBrush(serializedBrush);
            }
            else
            {
                return Brushes.DarkGray;
            }
        }
        private static Brush DeserializeSolidColorBrush(string serializedBrush)
        {
            string colorString = serializedBrush.Substring("sc:".Length);
            return new SolidColorBrush((Color)ColorConverter.ConvertFromString(colorString));
        }

        private static Brush DeserializeLinearGradientBrush(string serializedBrush)
        {
            string[] parts = serializedBrush.Split(':');
            string[] gradientParts = parts[3].Split('|');

            Point startPoint = ParsePoint(parts[1]);
            Point endPoint = ParsePoint(parts[2]);

            GradientStopCollection gradientStops = new GradientStopCollection();
            for (int i = 0; i < gradientParts.Length; i++)
            {
                string[] stopParts = gradientParts[i].Split(';');

                Color color = (Color)ColorConverter.ConvertFromString(stopParts[0]);
                double offset = double.Parse(stopParts[1], CultureInfo.InvariantCulture);
                gradientStops.Add(new GradientStop(color, offset));
            }

            LinearGradientBrush brush = new LinearGradientBrush(gradientStops, startPoint, endPoint);
            return brush;
        }

        private static Brush DeserializeRadialGradientBrush(string serializedBrush)
        {
            string[] parts = serializedBrush.Split(':');
            string[] gradientParts = parts[2].Split('|');

            Point center = ParsePoint(parts[1]);

            GradientStopCollection gradientStops = new GradientStopCollection();
            for (int i = 0; i < gradientParts.Length; i++)
            {
                string[] stopParts = gradientParts[i].Split(';');
                Color color = (Color)ColorConverter.ConvertFromString(stopParts[0]);
                double offset = double.Parse(stopParts[1], CultureInfo.InvariantCulture);
                gradientStops.Add(new GradientStop(color, offset));
            }

            RadialGradientBrush brush = new RadialGradientBrush(gradientStops);
            brush.Center = center;
            return brush;
        }

        private static Point ParsePoint(string pointString)
        {
            string[] pointParts = pointString.Split(';');
            return new Point(double.Parse(pointParts[0], CultureInfo.InvariantCulture), double.Parse(pointParts[1], CultureInfo.InvariantCulture));
        }

        private static string FormatGradientStops(GradientStopCollection gradientStops)
        {
            string result = string.Empty;
            for (int i = 0; i < gradientStops.Count; i++)
            {
                GradientStop stop = gradientStops[i];
                string colorHex = ColorToHex(stop.Color);
                result += colorHex + ";" + stop.Offset.ToString(CultureInfo.InvariantCulture);

                // Einfügen eines Trennzeichens, außer bei der letzten Iteration
                if (i < gradientStops.Count - 1)
                {
                    result += "|";
                }
            }
            return result;
        }

        private static string ColorToHex(Color color)
        {
            return $"#{color.A:X2}{color.R:X2}{color.G:X2}{color.B:X2}";
        }


        public static Brush DarkenBrush(Brush brush, double darken)
        {
            if (brush != null)
            {
                SolidColorBrush inputBrush = brush as SolidColorBrush;

                // Get the color of the fill brush
                Color fillColor = inputBrush.Color;

                // Create a darker version of the color (reduce the RGB values)
                Color darkerColor = Color.FromArgb(fillColor.A,
                                                   (byte)(fillColor.R * darken),
                                                   (byte)(fillColor.G * darken),
                                                   (byte)(fillColor.B * darken));

                // Create a new SolidColorBrush for the stroke with the darker color
                SolidColorBrush darkerBrush = new SolidColorBrush(darkerColor);

                // Assuming `myRectangle` is your Rectangle control
                return darkerBrush;
            }
            else
            {
                throw new ArgumentException("Unsupported brush type");
            }
        }
    }
}
